#include "TcpConnection.h"
#include <sstream>
#include <sys/socket.h>
#include <iostream>


#include "EventLoop.h"




TcpConnection::TcpConnection(int fd,EventLoop* loop)
:_socketIO(fd),
_sock(fd),
_localAddr(getLocalAddr()),
_peerAddr(getPeerAddr()),
_loop(loop)
{

}

TcpConnection::~TcpConnection()
{

}

void TcpConnection::send(const std::string & msg )
{
    _socketIO.writen(msg.c_str(),msg.length());
}

std::string TcpConnection::receive()
{
    char buf[65535]={0};
    _socketIO.readLine(buf,sizeof(buf));
    return std::string(buf);
}

std::string TcpConnection::toString()
{
    std::ostringstream oss;
    oss<<"local IP = "<<_localAddr.ip() \
        <<" local port = "<<_localAddr.port() \
        <<"peer IP = "<<_peerAddr.ip() \
        <<" peer port = "<<_peerAddr.port();
    return oss.str();

}

InetAddress TcpConnection::getPeerAddr()
{
    sockaddr_in addr;
    /**
     * int getsockname(int sockfd, struct sockaddr *restrict addr,
                       socklen_t *restrict addrlen);
        获取本地ip和端口
     */
    socklen_t len = sizeof(sockaddr_in);
    int ret = getsockname(_sock.fd(),(sockaddr*)&addr,&len);
    if(ret < 0)
    {
        perror("getsockname");
        exit(-1);
    }
    return InetAddress(addr);
}

InetAddress TcpConnection::getLocalAddr()
{
    sockaddr_in addr;
    /**
     * 获得对端ip和端口
     * int getpeername(int sockfd, struct sockaddr *restrict addr,
                       socklen_t *restrict addrlen);
     */
    socklen_t len = sizeof(sockaddr_in);
    int ret = getpeername(_sock.fd(),(sockaddr*)&addr,&len);
    if(ret < 0)
    {
        perror("getpeername");
        exit(-1);
    }
    return InetAddress(addr);
}


void TcpConnection::setOnNewConnection(const TcpConnectionCallback& cb)
{
    _onNewConnectionCb = cb;
}
void TcpConnection::setMessageCallback(const TcpConnectionCallback& cb)
{
    _onMessageCb = cb;
}
void TcpConnection::setCloseCallback(const TcpConnectionCallback& cb)
{
    _onCloseCb = cb;
}

void TcpConnection::handleNewConnectionCallback()
{
    if (_onNewConnectionCb)
    {
        
        _onNewConnectionCb(shared_from_this());
    }
    else
    {
        std::cout<<"_onNewConnectionCb is null"<<std::endl;
    }
    
}
void TcpConnection::handleMessageCallback()
{
    if (_onMessageCb)
    {
        _onMessageCb(shared_from_this());
    }
    else
    {
        std::cout<<"_onMessageCb is null"<<std::endl;
    }
    
}
void TcpConnection::handleCloseCallback()
{
    if (_onCloseCb)
    {
        _onCloseCb(shared_from_this());
    }
    else
    {
        std::cout<<"_onCloseCb is null"<<std::endl;
    }
    
}

bool TcpConnection::isClosed() const
{
    char buf[10]={0};
    int ret = recv(_sock.fd(),buf,sizeof(buf),MSG_PEEK);
    return (0 == ret);
}

void TcpConnection::sendInLoop(const std::string & msg)
{
    //如果_eventLoop为空，说明当前线程不是事件循环线程，那么就直接发送数据
    if (_loop)
    {
        _loop->runInLoop(std::bind(&TcpConnection::send,this,msg));
    }
    else
    {
        std::cout<<"_loop is null"<<std::endl;
    }

}